﻿using System.Collections.Generic;
using AutoUnitTest.Common;
using Moq;

namespace AutoUnitTest.Tests
{
    public static class MoqStubsAndMocks
    {
        public static Graph ClassGraph()
        {
            var mockGraph = new Mock<Graph>();

            var classVertex = new Vertex(new VertexType("class"), "System.MoqClass", 1);
            var methodVertex = new Vertex(new VertexType("function"), "MoqFunc1", 2);
            var accessVertex = new Vertex(new VertexType("L"), "public", 3);
            var returnVertex = new Vertex(new VertexType("type"), "System.Int32", 4);
            var paramVertex = new Vertex(new VertexType("field"), "p1", 5);
            var paramTypeVertex = new Vertex(new VertexType("type"), "System.Int32", 6);

            var classFuncEdge = new Edge(new EdgeType("m"), 1, methodVertex, classVertex);
            var funcAccessEdge = new Edge(new EdgeType("L"), 2, accessVertex, methodVertex);
            var funcReturnEdge = new Edge(new EdgeType("t"), 3, returnVertex, methodVertex);
            var paramFuncEdge = new Edge(new EdgeType("p"), 4, paramVertex, methodVertex);
            var paramTypeParamEdge = new Edge(new EdgeType("t"), 5, paramTypeVertex, paramVertex);

            classVertex.IncomingEdges.Add(classFuncEdge);
            accessVertex.OutgoingEdges.Add(funcReturnEdge);
            paramTypeVertex.OutgoingEdges.Add(paramTypeParamEdge);
            paramVertex.IncomingEdges.Add(paramTypeParamEdge);
            paramVertex.OutgoingEdges.Add(paramFuncEdge);
            returnVertex.OutgoingEdges.Add(funcReturnEdge);
            methodVertex.OutgoingEdges.Add(classFuncEdge);
            methodVertex.IncomingEdges.AddRange(new List<Edge> { funcAccessEdge, paramFuncEdge, funcReturnEdge });

            mockGraph.Setup(g => g.VertexList).Returns(new List<Vertex>{
                                                                           classVertex,methodVertex,
                                                                           accessVertex,returnVertex,
                                                                           paramVertex,paramTypeVertex});

            mockGraph.Setup(g => g.EdgeList).Returns(new List<Edge>
                                                     {
                                                         classFuncEdge,funcAccessEdge,
                                                         funcReturnEdge,paramFuncEdge,
                                                         paramTypeParamEdge
                                                     });

            return mockGraph.Object;
        }

        public  static Graph MethodBodyWithIfGraph()
        {
            var methGraph = new Mock<Graph>();

            var vClass = new Vertex(new VertexType("class"), "Program", 10);
            var vMethod = new Vertex(new VertexType("function"), "Func1", 1);
            var vMethodParameter = new Vertex(new VertexType("field"), "cond", 2);
            var vMethodParamType = new Vertex(new VertexType("type"), "System.Boolean", 3);
            var vMethodAccess = new Vertex(new VertexType("L"), "public", 4);
            var vMethodReturn = new Vertex(new VertexType("type"), "System.Void", 5);
            var vExpr = new Vertex(new VertexType("expression"), "if", 6);
            var vExprParam = new Vertex(new VertexType("parameter"), "cond", 7);
            var vExprParamType = new Vertex(new VertexType("type"), "System.Boolean", 8);

            var eClassMethod = new Edge(new EdgeType("m"), 1, vMethod, vClass);
            var eMethodAccess = new Edge(new EdgeType("L"), 2, vMethodAccess, vMethod);
            var eMethodReturn = new Edge(new EdgeType("t"), 3, vMethodReturn, vMethod);
            var eParamMethod = new Edge(new EdgeType("p"), 4, vMethodParameter, vMethod);
            var eMethodParamType = new Edge(new EdgeType("t"), 5, vMethodParamType, vMethodParameter);
            var eExpr = new Edge(new EdgeType("ex"), 6, vExpr, vMethod);
            var eExprParam = new Edge(new EdgeType("p"), 7, vExprParam, vExpr);
            var eExprParamType = new Edge(new EdgeType("t"), 7, vExprParamType, vExprParam);


            methGraph.Setup(g => g.VertexList).Returns(new List<Vertex>()
                                                       {
                                                           vClass,
                                                           vMethod,
                                                           vMethodParameter,
                                                           vMethodParamType,
                                                           vMethodAccess,
                                                           vMethodReturn,
                                                           vExpr,
                                                           vExprParam,
                                                           vExprParamType
                                                       });
            methGraph.Setup(g => g.EdgeList).Returns(new List<Edge>()
                                                     {
                                                         eClassMethod,
                                                         eMethodAccess,
                                                         eMethodReturn,
                                                         eMethodParamType,
                                                         eParamMethod,
                                                         eExpr,
                                                         eExprParam,
                                                         eExprParamType
                                                     });
            return methGraph.Object;
        }
    }
}